#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <assert.h>
#include <mysql/mysql.h>
#include "../comm/log.hpp"
#include "../comm/util.hpp"
// 1.将本地题库加载到内存中
// 2.提供对外访问的接口


/*  MySQL 版本*/
namespace ns_model
{
    using namespace std;
    using namespace ns_log;
    using namespace ns_util;

    struct Question
    {
        string number; // 题目编号
        string tile;   // 题目标题
        string star;   // 题目难度
        int cpu_limit; // 运行时间限制
        int mem_limit; // 运行空间限制
        string desc;   // 题目描述
        string header; // 题目预代码
        string test;   // 测试文件
    };
    const string tablename = "oj_questions";
    const string Dbname = "oj";
    const string host = "127.0.0.1";
    const string user = "qiangsir";
    const uint16_t port = 3306;
    const string password = "Ylq&123456789";

    class Model
    {
    public:
        Model()
        {
        }
        bool mysqlQuery(const std::string& sql,vector<Question>* questions)
        {
            MYSQL* my = mysql_init(nullptr);
            if(mysql_real_connect(my,host.c_str(),user.c_str(),password.c_str(),
                Dbname.c_str(),port,nullptr,0) == nullptr)
            {
                LOG(Level::FATAL)<<"数据库连接失败"<<mysql_error(my)<<"\n";
                return false;
            }
            LOG(INFO) << "连接数据库成功!" << "\n";
            // 执行语句
            if(0 != mysql_query(my,sql.c_str()))
            {
                LOG(WARNING)<<"sql 执行失败"<<"\n";
                return false;
            }
            //  转储数据
            MYSQL_RES* res = mysql_store_result(my);
            // 获取行列数
            int rows = mysql_num_rows(res);
            int cols = mysql_num_fields(res);
            // 获取数据
            MYSQL_ROW row;
            Question q;
            for(int i = 0;i < rows;i++)
            {
                row = mysql_fetch_row(res);
                q.number = row[0];
                q.tile = row[1];
                q.star = row[2];
                q.desc = row[3];
                q.header = row[4];
                q.test =row[5];
                q.cpu_limit =atoi(row[6]);
                q.mem_limit = atoi(row[7]);
                questions->push_back(q);
            }
            mysql_free_result(res);
            mysql_close(my);
            return true;
        }
        bool getAllQuestions(vector<Question>* qs)
        {
            string sql = "select * from ";
            sql += tablename;
            if(mysqlQuery(sql,qs)) return true;
            else return false;
        }
        bool getOneQuestion(const std::string& number,Question* q)
        {
            bool ret = false;
            string sql = "select * from ";
            sql += tablename;
            sql += " where id=";
            sql += number;
            vector<Question> tmp;
            if(mysqlQuery(sql,&tmp)) 
            {
                if(tmp.size() == 1)
                {
                    *q = tmp[0];
                    ret = true;
                }
            }
            return ret;
        }
        ~Model()
        {
        }
    };
}